#include "dxut.h"
#include "dx_util.h"

void CreateVertexShader(ID3D11Device* pd3dDevice, WCHAR* shaderFileName, char* shaderFuncName, 
						DWORD dwShaderFlags, ID3D11VertexShader** ppVertexShader)
{
	HRESULT hr;
	SAFE_RELEASE(*ppVertexShader)
    ID3DBlob* pVertexShaderBuffer = NULL;
	ID3DBlob* pErrorBuffer = NULL;

    if( SUCCEEDED( D3DX11CompileFromFile( shaderFileName, NULL, NULL, shaderFuncName, "vs_5_0", dwShaderFlags, 0, NULL,
                                     &pVertexShaderBuffer, &pErrorBuffer, NULL ) ))
	{
		hr = pd3dDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(),
												  pVertexShaderBuffer->GetBufferSize(), NULL, ppVertexShader ) ;
		if (FAILED(hr))
			::MessageBoxA(0, shaderFuncName, "Fail to create vertex shader:", 0);
	}
	else
		MessageBoxA(NULL, (LPCSTR)pErrorBuffer->GetBufferPointer(), "VS Compile Error",0);
	SAFE_RELEASE(pErrorBuffer);
    SAFE_RELEASE(pVertexShaderBuffer);

}

void CreatePixelShader(ID3D11Device* pd3dDevice, WCHAR* shaderFileName, char* shaderFuncName, 
						DWORD dwShaderFlags, ID3D11PixelShader** ppPixelShader)
{
	HRESULT hr;
	SAFE_RELEASE(*ppPixelShader)
    ID3DBlob* pPixelShaderBuffer = NULL;
	ID3DBlob* pErrorBuffer = NULL;

	if(SUCCEEDED( D3DX11CompileFromFile( shaderFileName, NULL, NULL, shaderFuncName, "ps_5_0", dwShaderFlags, 0, NULL,
                                     &pPixelShaderBuffer, &pErrorBuffer, NULL ) ))
	{
		hr = pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(),
												 pPixelShaderBuffer->GetBufferSize(), NULL, ppPixelShader ) ;
		if (FAILED(hr))
			::MessageBoxA(0, shaderFuncName, "Fail to create pixel shader:", 0);
	}
	else
		MessageBoxA(NULL, (LPCSTR)pErrorBuffer->GetBufferPointer(), "PS Compile Error",0);

	SAFE_RELEASE(pErrorBuffer);
	SAFE_RELEASE(pPixelShaderBuffer)
}

void CreateGeometryShader(ID3D11Device* pd3dDevice, WCHAR* shaderFileName, char* shaderFuncName, 
						DWORD dwShaderFlags, ID3D11GeometryShader** ppGeometryShader)
{
	HRESULT hr;
	SAFE_RELEASE(*ppGeometryShader)
    ID3DBlob* pGeometryShaderBuffer = NULL;
	ID3DBlob* pErrorBuffer = NULL;

	if(SUCCEEDED( D3DX11CompileFromFile( shaderFileName, NULL, NULL, shaderFuncName, "gs_5_0", dwShaderFlags, 0, NULL,
                                     &pGeometryShaderBuffer, &pErrorBuffer, NULL ) ))
	{
		hr = pd3dDevice->CreateGeometryShader( pGeometryShaderBuffer->GetBufferPointer(),
												 pGeometryShaderBuffer->GetBufferSize(), NULL, ppGeometryShader ) ;
		if (FAILED(hr))
			::MessageBoxA(0, shaderFuncName, "Fail to create geometry shader:", 0);
	}
	else
		MessageBoxA(NULL, (LPCSTR)pErrorBuffer->GetBufferPointer(), "GS Compile Error",0);

	SAFE_RELEASE(pErrorBuffer);
	SAFE_RELEASE(pGeometryShaderBuffer)
}

void CreateHullShader(ID3D11Device* pd3dDevice, WCHAR* shaderFileName, char* shaderFuncName, 
						DWORD dwShaderFlags, ID3D11HullShader** ppHullShader)
{
	HRESULT hr;
	SAFE_RELEASE(*ppHullShader)
    ID3DBlob* pHullShaderBuffer = NULL;
	ID3DBlob* pErrorBuffer = NULL;

	if(SUCCEEDED( D3DX11CompileFromFile( shaderFileName, NULL, NULL, shaderFuncName, "hs_5_0", dwShaderFlags, 0, NULL,
                                     &pHullShaderBuffer, &pErrorBuffer, NULL ) ))
	{
		hr = pd3dDevice->CreateHullShader( pHullShaderBuffer->GetBufferPointer(),
												 pHullShaderBuffer->GetBufferSize(), NULL, ppHullShader ) ;
		if (FAILED(hr))
			::MessageBoxA(0, shaderFuncName, "Fail to create hull shader:", 0);
	}
	else
		MessageBoxA(NULL, (LPCSTR)pErrorBuffer->GetBufferPointer(), "HS Compile Error",0);

	SAFE_RELEASE(pErrorBuffer);
	SAFE_RELEASE(pHullShaderBuffer)
}

void CreateDomainShader(ID3D11Device* pd3dDevice, WCHAR* shaderFileName, char* shaderFuncName, 
						DWORD dwShaderFlags, ID3D11DomainShader** ppDomainShader)
{
	HRESULT hr;
	SAFE_RELEASE(*ppDomainShader)
    ID3DBlob* pDomainShaderBuffer = NULL;
	ID3DBlob* pErrorBuffer = NULL;

	if(SUCCEEDED( D3DX11CompileFromFile( shaderFileName, NULL, NULL, shaderFuncName, "ds_5_0", dwShaderFlags, 0, NULL,
                                     &pDomainShaderBuffer, &pErrorBuffer, NULL ) ))
	{
		hr = pd3dDevice->CreateDomainShader( pDomainShaderBuffer->GetBufferPointer(),
												 pDomainShaderBuffer->GetBufferSize(), NULL, ppDomainShader ) ;
		if (FAILED(hr))
			::MessageBoxA(0, shaderFuncName, "Fail to create domain shader:", 0);
	}
	else
		MessageBoxA(NULL, (LPCSTR)pErrorBuffer->GetBufferPointer(), "DS Compile Error",0);

	SAFE_RELEASE(pErrorBuffer);
	SAFE_RELEASE(pDomainShaderBuffer)
}